#region using

using System;
using System.Web;
using BlogEngine.Core.Web.Controls;
using BlogEngine.Core;
using System.Net.Mail;
using System.Threading;
using System.Text.RegularExpressions;
using System.Data;
#endregion

/// <summary>
/// Replaces a word, regardless of case with a link.
/// Author: Clarence Klopfstein
/// Contact Via: http://www.ckurl.com
/// Adapted from code found here:
/// http://blog.madskristensen.dk/post/BBCode-extension-for-BlogEngineNET-12.aspx
/// 
/// Free to use, would appreciate a note that you are using it and credit being given... 
/// but not required.
/// 
/// Attached ASPX page and following directions in text document would allow you to edit 
/// the provided xml document from the admin section of the site.
/// </summary>
[Extension("Replaces Keywords with links", "1.2", "<a href=\"http://www.ckurl.com/techblog/page/Quicker-Links.aspx\">QL Author</a>")]
public class QuickerLinks
{
    static protected ExtensionSettings _settings = null;
	/// <summary>
	/// Hooks up an event handler to the Post.Saving event.
	/// </summary>
	public QuickerLinks()
	{
		Post.Saving += new EventHandler<BlogEngine.Core.SavedEventArgs>(Post_Saving);

        SetDefaultSettings();
	}

    protected void SetDefaultSettings()
    {
        ExtensionSettings settings = new ExtensionSettings("QuickerLinks");
        settings.AddParameter("WordToReplace", "Word To Replace", 150, true, true);
        settings.AddParameter("Link", "Link", 150, true);
        settings.AddParameter("Target", "Target", 20, true, true);
        settings.AddParameter("CollectClickStats", "CollectClickStats", 5, false);

        settings.AddValue("WordToReplace", "Quicker Links");
        settings.AddValue("Link", "http://www.ckurl.com/techblog/page/Quicker-Links.aspx");
        settings.AddValue("Target", "_blank");
        settings.AddValue("CollectClickStats", "False");

        settings.IsScalar = false;

        settings.Help = "<strong>Word to Replace:</strong> Will be the word you will replace with a link<br/>" +
            " <strong>Link:</strong> HTTP link to open<br/>" +
            " <strong>Target:</strong> _blank would open in a new window, if anything else is in this it will just default to default link behavior<br/>" +
            " <strong>Collect Click Stats:</strong> True or False, requires <a href=\"http://blog.madskristensen.dk/post/Count-clicks-on-external-links-in-ASPNET.aspx\"" +
            " target=\"_blank\">this extension</a> to work.<br/>" +
            " <strong>ALL FIELDS ARE REQUIRED - IF YOU ENTER INVALID DATA IT WILL BREAK THE EXTENSION</strong>";

        ExtensionManager.ImportSettings(settings);

        _settings = ExtensionManager.GetSettings("QuickerLinks");
    }

	/// <summary>
	/// Function to handle the post.saving event.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void Post_Saving(object sender, EventArgs e)
	{
		//TODO: Make this actually replace some code words with links!
		Post post = (Post)sender;
		string content = post.Content;
        DataTable table = _settings.GetDataTable();
        foreach (DataRow row in table.Rows)
        {
            bool CollectClickStats = Convert.ToBoolean(row["CollectClickStats"].ToString());

            FormatForPost(ref content, (string)row["WordToReplace"], (string)row["Link"], (string)row["Target"], CollectClickStats);
        }
		post.Content = content;
	}

	/// <summary>
	/// FormatForPost - Function adapted from 
	/// http://blog.madskristensen.dk/post/BBCode-extension-for-BlogEngineNET-12.aspx
	/// Changed to make into a link instead of a html tag
	/// </summary>
	/// <param name="content">Body of the post</param>
	/// <param name="rplText">Text to replace</param>
	/// <param name="url">Link to convert text to.</param>
	private void FormatForPost(ref string content, string rplText, string url, string target, bool redirect)
	{
		/***********
		/ Define regex options and variable.
		/***********/
		RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline;
		Regex REGEX = null;

		#region Test string with closing bracket before it, ie. <p>replaceword
		REGEX = new Regex("[>]" + rplText + "[ ]", options);

		QuickReplace(ref content, REGEX, " <a href=\"" + url +
			"\" " + (redirect == true ? "onclick=\"trackclick(this)\"" : "") + " target=\"" + target + "\">################</a> ", 1);
		#endregion

		#region Test string with these characters on the end <!;.?, ie. replaceword!
		REGEX = new Regex(rplText + "[!;.?,]", options);

		QuickReplace(ref content, REGEX, " <a href=\"" + url +
											"\" " + (redirect == true ? "onclick=\"trackclick(this)\"" : "") + " target=\"" + target + "\">################</a> ", 2);
		#endregion

		#region Test string with these characters on the end < ie. replaceword<br/>
		REGEX = new Regex("[ ]" + rplText + "[<]", options);

		QuickReplace(ref content, REGEX, " <a href=\"" + url +
											"\" " + (redirect == true ? "onclick=\"trackclick(this)\"" : "") + " target=\"" + target + "\">################</a> ", 3);
		#endregion

		#region Test plain string with a space at the start
		REGEX = new Regex("[ ]" + rplText, options);

		QuickReplace(ref content, REGEX, " <a href=\"" + url +
											"\" " + (redirect == true ? "onclick=\"trackclick(this)\"" : "") + " target=\"" + target + "\">################</a> ", 0);
		#endregion

		#region Test string with space at the end.
		REGEX = new Regex(rplText + "[ ]", options);

		QuickReplace(ref content, REGEX, " <a href=\"" + url +
											"\" " + (redirect == true ? "onclick=\"trackclick(this)\"" : "") + " target=\"" + target + "\">################</a> ", 0);
		#endregion

	}

	/// <summary>
	/// QuickReplace - Function adapted from
	/// http://blog.madskristensen.dk/post/BBCode-extension-for-BlogEngineNET-12.aspx
	/// Will replace all instances of the text in the post
	/// </summary>
	/// <param name="content">Body of the post</param>
	/// <param name="regexMatch">Regex it is trying to match</param>
	/// <param name="replaceString">URL String to replace with</param>
	private void QuickReplace(ref string content, Regex regexMatch, string replaceString, int regExFix)
	{
		Match m = regexMatch.Match(content);
		while (m.Success)
		{
			string tStr = replaceString.Replace("################", m.Value.ToString().Trim());
			switch (regExFix)
			{
				case 1:// Fix words that have > at the beginning
					tStr = tStr.Replace("<a", "><a").Replace(">>", ">");
					break;
				case 2:// Fix words that have !;.?, at the end
					tStr = tStr.Replace("<</a>", "</a><").Replace("!</a>", "</a>!").Replace(";</a>", "</a>;").Replace(".</a>", "</a>.").Replace("?</a>", "</a>?").Replace(",</a>", "</a>,");
					if (tStr.Contains("</a>< "))
					{
						tStr = tStr.TrimEnd(' ');
					}
					break;
				case 3:// Fix words that have < at the end.
					tStr = tStr.Replace("<</a>", "</a><");
					if (tStr.Contains("</a>< "))
					{
						tStr = tStr.TrimEnd(' ');
					}
					break;
			}
			content = content.Substring(0, m.Groups[0].Index) + tStr +
										content.Substring(m.Groups[0].Index +
										m.Groups[0].Length);
			m = regexMatch.Match(content);
		}
	}
}
